import { ParameterizedContext } from 'koa'
import Router, { IRouterParamContext } from 'koa-router'
import { Methods } from '../constant'
import Controllers from '../controllers'
import Services from '../services'
import Models from '../models'

const RouterInit = new Router({ prefix: '/v1' })

export type IPaths = {
  path: string
  fnName: string
  method: Methods
}
export type IConfig = {
  moduleName: string
  paths: IPaths[]
}

type IContext = ParameterizedContext<
  any,
  IRouterParamContext<any, any>,
  any
> & {
  model: any
  service: any
}

const base: IPaths[] = [
  { path: '/create', fnName: 'create', method: Methods.POST },
  { path: '/delete', fnName: 'delete', method: Methods.POST },
  { path: '/update', fnName: 'update', method: Methods.POST },
  { path: '/query', fnName: 'query', method: Methods.GET },
]

const config: IConfig[] = [
  {
    moduleName: 'User',
    paths: [
      {
        path: '/register',
        fnName: 'register',
        method: Methods.POST,
      },
      {
        path: '/login',
        fnName: 'login',
        method: Methods.POST,
      },
    ],
  },
].map((config) => {
  config.paths.push(...base)
  return config
})

/**
 * /v1/module/example/query
 */
config.forEach(async (route) => {
  const controller = Controllers[route.moduleName]
  route.paths.forEach((apis) => {
    RouterInit[apis.method](
      `/module/${route.moduleName.toLowerCase()}${apis.path}`,
      async (ctx) => {
        ;(ctx as IContext).model = Models[route.moduleName]
        ;(ctx as IContext).service = Services[route.moduleName]
        await controller[apis.fnName](ctx)
      },
    )
  })
})

export default RouterInit
